﻿using com.iot.core.annotation; 
using com.iot.core.boot.configuration;
using com.iot.core.exception;
using com.iot.core.infrastructure;
using com.iot.core.manager.id;
using com.iot.core.mongo;
using com.iot.ht.Controllers.htfile.data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;

namespace com.iot.ht.Controllers.htfile
{
    [ApiController]
    [Route("[controller]/[action]")]
    [Tag(Name = "文件上传", Description = "")]
    public class HtFileController : ControllerBase
    {
        const string TableName = "HtFile";


        [HttpPost]
        [Operation(Summary= "上传文件", Description ="" )]
        [Auth(AuthType.Login)]
        [Log(LogNeed = false, LogPin = false, LogPout = false, LogTemplete = "")]
        public HtFileDto Up([FromForm] IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                throw new MyException("文件错误");
            }
            var fcfg = Singleton<AppSettings>.Instance.Get<FileConfig>();
            if (file.Length > fcfg.MaxFileSize)
            {
                throw new MyException("文件太大");
            }
            var m = new HtFileDto
            {
                Id = HtIdManager.Current.NextLong(),
                Name = file.FileName,
                Memo = "",
                Url = ""
            };
            var db = new MongoHtFileDto
            {
                Id = m.Id,
                Name = m.Name,
                Data = null,
                Memo = m.Memo,
                Size = file.Length,
                Gid = HtIdManager.Current.NextGuid(),
                FileId = ""
            };

            var coll =  MongoDBHelper.Current.GetCollection<MongoHtFileDto>(TableName);

            if (file.Length < 12 * 1024 * 1024)
            {
                db.Data = new byte[file.Length];
                using (var ms = file.OpenReadStream())
                {
                    ms.Read(db.Data, 0, Convert.ToInt32(db.Size));
                }
            }
            else
            {
                var bucket =  MongoDBHelper.Current.NewBucket();
                using (var ms = file.OpenReadStream())
                {
                    var oid = bucket.UploadFromStream(m.Name, ms);
                    db.FileId = oid.ToString();
                }
            }

            coll.InsertOne(db);

            var url = fcfg.FixHttpPrev;
            if (string.IsNullOrEmpty(url))
            {
                url = com.iot.core.util.RequestUtil.GetHttpPrev(this.HttpContext);
            }
            url += $"/htfile/show?id={m.Id}";
            m.Url = url;
             
            return m;

        }


        [HttpGet]
        [Operation(Summary = "显示文件", Description = "")]
        [Auth(AuthType.None)]
        [Log(LogNeed = false, LogPin = false, LogPout = false, LogTemplete = "")]
        public IActionResult Show([FromQuery] long Id)
        {
            return ShowDown(Id, true); 
        }


        [HttpGet]
        [Operation(Summary = "下载文件", Description = "")]
        [Auth(AuthType.None)]
        [Log(LogNeed = false, LogPin = false, LogPout = false, LogTemplete = "")]
        public IActionResult Down([FromQuery] long Id)
        {
            return ShowDown(Id, false);
        }

        private IActionResult ShowDown(long Id,bool bShow=false)
        {
            var ContentType = "application/x-download";           
            var coll = MongoDBHelper.Current.GetCollection<MongoHtFileDto>(TableName);
            var m = coll.Find(a => a.Id == Id).FirstOrDefault();
            if (bShow)
            {
                ContentType = GetContentType(m.Name);
            }
            if (string.IsNullOrEmpty(m.FileId))
            {
                var buff = m.Data;
                var destination = new MemoryStream(buff);
                destination.Seek(0, SeekOrigin.Begin);
                return File(destination, ContentType, m.Name);

            }
            else
            {

                var bucket = MongoDBHelper.Current.NewBucket();
                Stream destination = new MemoryStream();
                bucket.DownloadToStream(MongoDB.Bson.ObjectId.Parse(m.FileId), destination);
                destination.Seek(0, SeekOrigin.Begin);
                return File(destination, ContentType, m.Name);

            }
        }



        public static string GetContentType(string path)
        {
            var provider = new FileExtensionContentTypeProvider();
            string contentType;
            if (!provider.TryGetContentType(path, out contentType))
            {
                contentType = "application/octet-stream";
            }
            return contentType;
        }


    }
}
